// 基于axios封装网络请求


import Theaxios from "axios"
import router from '@/router'
import { Notify } from "vant";
import { getToken, removeToken, setToken } from '@/utils/token.js'

import { getNewTokenAPI } from '@/api'

const axios = Theaxios.create({
    baseURL: ' http://toutiao.itheima.net',
    timeout: 20000 //请求20s无响应，直接判定超时
})

// 添加请求拦截器
axios.interceptors.request.use(function(config) {
    // 在发送请求之前做些什么
    // 目标：统一携带token
    // 判断本地有token再携带，判断具体pi/index.js里如果没有携带Authorization，再添加上去
    // 未定义叫undefined，null具体的值得赋予才叫空
    // ?.可选链操作符(解决vscode代码自动排版后可用)，如果前面对象没有length，整个表达式原地返回undefined
    // 如果getToken()在原地有值token字符串，才能调用length获取长度
    // if (getToken()?.length > 0 && config.headers.Authorization === undefined) {
    //     config.headers.Authorization = `Bearer ${getToken()}`
    // }
    return config;
}, function(error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
// 本质：就是一个函数
axios.interceptors.response.use(function(response) {
    // 当http响应状态码为2xx，3xx时，就进入这里
    // 对响应数据做点什么
    return response;
}, async function(error) {
    // http响应状态码为4xx，5xx时报错进入这里
    // 对响应错误做点什么
    // console.dir(error)
    // 只有401才代表身份过期，才需要跳转登录
    if (error.response.status === 401) {
        // 不能使用this.$router（因为这里的this不是vue组件对象，无法调用$router）
        // 解决方案：this.$router为了拿到router路由对象，直接去
        // 上面引入@/router下的路由对象
        // Notify({
        //         type: 'warning',
        //         message: '身份已过期，重新登录'
        //     })
        // 方式一：清除token，强制跳转登录页，用户有感知
        removeToken() //先清除token，才能让路由守卫判断失效，放行去 登录页
        router.push(`/login?path=${router.currentRoute.fullPath}`)

        // 方式2：使用refresh_token换回新的token再继续使用，JS代码实现，用户无感知（效果好）
        // 调用api接口，获取到新的token
        // const res = await getNewTokenAPI()
        //     //新的token回来之后，我们要做什么
        //     // 1.更新token在本地
        // setToken(res.data.data.token)
        //     // 2.更新新的token在请求头里
        // error.config.headers.Authorization = `Bearer ${res.data.data.token}`
        //     // 3.未完成这次请求，再一次发起
        //     //error.config就是上一次请求的配置对象 
        //     // 结果我们要return回原本的逻辑页面调用的地方-还是return回去一个promise对象
        // return axios(error.config)

        // 
    } else if (error.response.status === 500 && error.config.url === '/v1_0/authorizations' && error.config.method === 'put') {
        // 刷新的refresh_token也过期了
        removeToken()
        localStorage.clear() //清除localStorage里所有值
        Notify({
            type: 'warning',
            message: '身份已过期，重新登录'
        })
        router.replace('/login')
    }
    return Promise.reject(error);
});

export default ({ url, method = 'GET', params = {}, data = {}, headers = {} }) => {
    return axios({
        url,
        method,
        params,
        data,
        headers
    })
}